package com.godenwater.recv.service;

import java.io.*;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import com.godenwater.framework.config.SpringUtils;
import com.godenwater.yanyu.body.*;
import com.godenwater.recv.server.all.RtuConfig;
import com.godenwater.web.manager.StationManager;
import com.godenwater.web.rtu.model.RtuStationModel;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.godenwater.core.spring.Application;
import com.godenwater.core.spring.BaseDao;
import com.godenwater.recv.model.CommonMessage;
import com.godenwater.yanyu.IMessageHeader;
import com.godenwater.yanyu.Symbol;
import com.godenwater.yanyu.YYBuilder;
import com.godenwater.yanyu.YYParser;
import com.godenwater.yanyu.utils.ByteUtil;
import com.godenwater.yanyu.command.DownCommand;

/**
 * 1.1报文消费者
 *
 * @author lipujun
 * @ClassName: MessageConsumer
 * @Description: 通过线程的方式将“报文”解析，然后入库，这是消息进行处理的第一个环节
 * <p>
 * 注意：只启动一个消费者
 * @date Mar 14, 2013
 */
public class MessageYyConsumer extends AbstractMessageConsumer implements
        Runnable {

    private static Logger logger = LoggerFactory
            .getLogger(MessageYyConsumer.class);

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat sdfmm = new SimpleDateFormat("yyMMddHHmmss");
    private static long DAY = 24 * 60 * 60 * 1000;

    private static long HOUR = 60 * 60 * 1000;

    private static String KEY = "messages";

    private BaseDao dao = SpringUtils.getBean("baseDao");

    public MessageYyConsumer() {

    }

    @Override
    public void run() {

    }

    /**
     * 处理业务逻辑
     * <p>
     * 第一步：原始报文入库
     * <p>
     * 第二步：判断单报、多报。单报写“入库队列”；多报写文件，并根据最后一条报文写“合并队列”
     *
     * @param message
     */
    public void process(String channel, CommonMessage message, String replayMsg, String ip, Integer port) throws Exception {
        boolean crcFlag = true;

        IMessageHeader header = (IMessageHeader) message.getHeader();

        // 解析报文体
        String stcd = "" + YYParser.parseStcd(header.getCenterAddr(), header.getStationAddr());

        byte[] content = message.getContent();

        byte[] funcCode = header.getFuncCode();

        String id = UUID.randomUUID().toString();
        // 写入原始报文库
        String msgstr = YYBuilder.toHexString((IMessageHeader) message.getHeader(), Symbol.UP) + ByteUtil.toHexString(content) + ByteUtil.toHexString(message.getEOF()) + ByteUtil.toHexString(message.getCRC());

        switch (funcCode[0]) {
            case 0X1B:// 表示雨量加报。
            case 0X19:// 表示水位加报。
                SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
                byte[] sendDate = new byte[5];
                System.arraycopy(content, 0, sendDate, 0, sendDate.length);
                String sendtime = ByteUtil.bcd2Str(sendDate);
                Date viewtime = sdf.parse(sendtime);
                // 写入原始报文库
                this.writeRtuMessage(id, stcd, "YY", channel, ByteUtil.toHexString(funcCode), 1, viewtime, 1, 1, msgstr, crcFlag, replayMsg, ip, port, 0);
                logger.debug("原始报文入库：", msgstr);
                break;
            case 0X0B:// 表示雨量加报。
            case 0X09:// 表示水位加报。
            case 0X07://召测报文
            case 0X0E:// 整点报
                SimpleDateFormat sdf5 = new SimpleDateFormat("yyMMddHHmm");
                byte[] sendDate5 = new byte[5];
                System.arraycopy(content, 0, sendDate5, 0, sendDate5.length);
                String sendtime5 = ByteUtil.bcd2Str(sendDate5);
                Date viewtime5 = sdf5.parse(sendtime5);
                // 写入原始报文库
                this.writeRtuMessage(id, stcd, "YY", channel, ByteUtil.toHexString(funcCode), 1, viewtime5, 1, 1, msgstr, crcFlag, replayMsg, ip, port, 0);
                logger.debug("原始报文入库：", msgstr);
                //取出设备对应的测站信息
                RtuStationModel station = StationManager.getInstance().getStation(stcd);
                if (station != null) {
                    //燕禹和江西需要添加此拆分
                    //1.1、写入雨量表,测站类型为1，表示雨量站
                    if (org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(station.getSttp(), "1")) {
                        Up0EBody up0EBody01 = YYParser.parse0EBody(content);
                        // 根据类型判断是写入雨量还是水位
                        int ff26 = ByteUtil.bytesToUshort(up0EBody01.getF1());//应该取整数//processSymbolHex(up0EBody01.getF1(), 1);
                        int ff20 = ByteUtil.bytesToUshort(up0EBody01.getF2());//应该取整数//processSymbolHex(up0EBody01.getF2(), 1);
                        int ff1A = ByteUtil.bytesToUshort(up0EBody01.getF3());//应该取整数//processSymbolHex(up0EBody01.getF3(), 1);
                        // 根据类型判断是写入雨量还是水位
                        byte[] ff4 = up0EBody01.getF4();
                        byte[] ff6 = up0EBody01.getF6();
                        writeYYRainData(stcd, funcCode[0], viewtime5, processSymbolF4H(ff4), ff20, ff1A, ff6);
                    }
                    //1.2、写入水位表,测站类型为2，表示水位站
                    if (org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(station.getSttp(), "2")) {
                        Up0EBody up0EBody02 = YYParser.parse0EBody(content);
                        byte[] ff5 = up0EBody02.getF5();
                        byte[] ff6 = up0EBody02.getF6();
                        writeYYRiverData(stcd, funcCode[0], viewtime5, processSymbolF5H(ff5), ff6);
                    }
                    //1.3、写入雨量表,测站类型为3，表示雨量站和水位站
                    if (org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(station.getSttp(), "3")) {
                        Up0EBody up0EBody03 = YYParser.parse0EBody(content);

                        int ff20 = ByteUtil.bytesToUshort(up0EBody03.getF2());//应该取整数//processSymbolHex(up0EBody01.getF2(), 1);
                        int ff1A = ByteUtil.bytesToUshort(up0EBody03.getF3());//应该取整数//processSymbolHex(up0EBody01.getF3(), 1);
                        //String ff20 = processSymbolHex(up0EBody03.getF2(), 1);//时段雨量
                        //String ff1A = processSymbolHex(up0EBody03.getF3(), 1);//日雨量
                        // 根据类型判断是写入雨量还是水位
                        byte[] ff4 = up0EBody03.getF4();
                        byte[] ff5 = up0EBody03.getF5();
                        byte[] ff6 = up0EBody03.getF6();
                        writeYYData(stcd, funcCode[0], viewtime5, processSymbolF4H(ff4), processSymbolF5H(ff5), ff20, ff1A, ff6);
                    }
                    //1.4、写入闸位表,测站类型为10，表示闸位站
                    if (org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(station.getSttp(), "10")) {
                        Up0E10Body up0EBody10 = YYParser.parse0E10Body(content);
                        byte[] f8 = up0EBody10.getF8();//闸位数据
                        byte[] ff6 = up0EBody10.getF6();
                        writeYYZhaweiData(stcd, funcCode[0], viewtime5, processSymbolF8H(f8), ff6);
                    }

                    //1.5、写入流速表,测站类型为16，表示流速站
                    if (org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(station.getSttp(), "16")) {
                        Up0E16Body up0EBody16 = YYParser.parse0E16Body(content);
                        int ff20 = ByteUtil.bytesToUshort(up0EBody16.getF2());//应该取整数//processSymbolHex(up0EBody01.getF2(), 1);
                        int ff1A = ByteUtil.bytesToUshort(up0EBody16.getF3());//应该取整数//processSymbolHex(up0EBody01.getF3(), 1);
                        byte[] f8 = up0EBody16.getF8();//流速数据
                        byte[] ff6 = up0EBody16.getF6();
                        byte[] ff5 = up0EBody16.getF5();
                        byte[] ff4 = up0EBody16.getF4();
                        writeYYLiusuData(stcd, funcCode[0], viewtime5, processSymbolF9H(f8), processSymbolF4H(ff4), processSymbolF5H(ff5), ff20, ff1A, ff6);
                    }

                    //1.5、写入流量表,测站类型为17，表示流量站
                    if (org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(station.getSttp(), "17")) {
                        Up0E17Body up0EBody17 = YYParser.parse0E17Body(content);
                        byte[] f8 = up0EBody17.getF8();//流量仪器号
                        byte[] f9 = up0EBody17.getF9();//流量数据
                        byte[] ff6 = up0EBody17.getF6();
                        writeYYOttData(stcd, funcCode[0], viewtime5, ByteUtil.bytesToUbyte(f8), processSymbolF9H(f9), ff6);
                    }
                    if (org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(station.getSttp(), "14")) {
                        Up0E14Body up0EBody14 = YYParser.parse0E14Body(content);
                        byte[] ff6 = up0EBody14.getF6();
                        int ff31 = ByteUtil.bytesToUshort(up0EBody14.getF9());//日蒸发数据数据
                        writeYYZhengfaData(stcd, funcCode[0], viewtime5, ff31, ff6);
                    }

                } else {
                    //测站不存在
                    writeRtuAlarm(stcd, ByteUtil.byteToHexString(funcCode), "", new Date(), "测站不存在！");
                    logger.info(stcd + " 测站不存在！");
                }
                break;
            case 0X0C:
                //写入测试数据
                break;
            case 0X0A:// 雨量固态数据
                this.writeRtuMessage(id, stcd, "YY", channel, ByteUtil.toHexString(funcCode), 1, new Date(), 1, 1, msgstr, crcFlag, replayMsg, ip, port, 0);
                logger.debug("原始报文入库：", msgstr);
                //首先写入文件，当报文里有结束报文的时候合并报文处理数据
                process0A(msgstr);
                break;
            case 0X06:// 水位固态数据
                // 3.2写入原始报文库
                this.writeRtuMessage(id, stcd, "YY", channel, ByteUtil.toHexString(funcCode), 1, new Date(), 1, 1, msgstr, crcFlag, replayMsg, ip, port, 0);
                logger.debug("原始报文入库：", msgstr);
                process06(msgstr);
                break;
            default:
                break;
        }

    }

    public String[] processSymbolF4H(byte[] value) {
        String[] dh12 = new String[12];
        int pos = 0;
        for (int i = 0, len = value.length; i < len; i++) {
            int intvalue = ByteUtil.bytesToUbyte(new byte[]{value[i]});

            if (intvalue == 255) {
                dh12[pos] = "FF";
            } else {
                String itemvalue = Integer.toString(intvalue);

                // 燕禹68字节协议中，记录的是翻斗的次数，一次0.5mm,需要将此数据翻转
                BigDecimal bd = new BigDecimal(itemvalue);
                BigDecimal val = bd.multiply(new BigDecimal("0.5"));
                dh12[pos] = val.toString();
            }

            pos++;
        }
        return dh12;
    }

    /**
     * lhc 把固态雨量数据报文写入文件
     *
     * @param msg
     */
    public void process0A(String msg) throws IOException, ParseException {
        String path = RtuConfig.getMsgRcvPath();
        String stcd = String.valueOf(Integer.parseInt(msg.substring(4, 6), 16));
        String index = String.valueOf(Integer.parseInt(msg.substring(10, 14), 16));
        String endStr = msg.substring(msg.length() - 6, msg.length() - 4);
        //System.out.println(endStr);
        path = path + "/YY/rcv/" + stcd + "/0A";
        File fullPathDir = new File(path);
        if (fullPathDir != null && !fullPathDir.exists()) {
            fullPathDir.mkdirs();
        }
        // 2、写入报文文件
        String fileName = index + ".msg";
        File file = new File(path, fileName);
        try {
            org.apache.commons.io.FileUtils.writeStringToFile(file, msg, "UTF8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //最后结尾是03代表数据发送结束，合并报文，统计五分钟数据入库.
        if (endStr.equals("03")) {
            process0AEnd(stcd, path, Integer.parseInt(index));
        }

    }

    /**
     * 合并固态水位数据报文并入库五分钟数据
     */
    public void process0AEnd(String stcd, String path, int sequence) throws IOException, ParseException {
        //取出文件夹下的所有问题，按照名称排序
        SimpleDateFormat sdf5 = new SimpleDateFormat("yyMMddHHmm");
        File fullPathDir = new File(path);
        File[] downFile = fullPathDir.listFiles();
        String content = "";
        if (downFile.length == sequence) {
            for (int i = 1; i <= sequence; i++) {
                String tempPath = path + "/" + i + ".msg";
                String msg = readToString(tempPath);
                content += msg.substring(14, msg.length() - 6);
            }
            java.text.SimpleDateFormat newstr = new java.text.SimpleDateFormat("yyMMddHHmm");
            //取出测站基本信息,写入业务数据库
            RtuStationModel station = StationManager.getInstance().getStation(stcd);
            logger.info("测站号码：" + stcd);
            if (station != null) {
                String stcd8 = station.getStcd8();
                String[] listRain = content.split("dddddd");
                List<Date> listTm = new ArrayList<Date>();
                for (int i = 1; i < listRain.length; i++) {
                    String rain = listRain[i];
                    if (rain.length() > 6) {
                        String tm = rain.substring(0, 6);
                        String hour = rain.substring(6);
                        while (hour.length() > 0) {
                            String minte = hour.substring(0, 4);
                            Date tempTm = newstr.parse(tm + minte);
                            listTm.add(tempTm);
                            hour = hour.substring(4);
                        }
                    }
                }
                //循环处理成5分钟的类型数据
                listTm = getFive(listTm);
                //处理结果集入库
                Map<Date, Integer> rainMap = getRain(listTm);
                //处理入库
                for (Date key : rainMap.keySet()) {
                    Date tm = key;
                    Integer coun = (Integer) rainMap.get(key);
                    double rain = coun * 0.5;//雨量翻斗次数 每0.5翻斗一次
                    try {
                        writeYYConnvertData(stcd, tm, "1", 23, rain, 888);//入库程序不处理固态数据提取过来的数据，标识改为不处理数据。
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        //清空文件夹
        delAllFile(path);
    }

    public Map<Date, Integer> getRain(List<Date> listDate) {
        // List<Map<Date, Integer>> listTm = new ArrayList<Map<Date, Integer>>();
        Map tempMap = new HashMap();
        for (int i = 0; i < listDate.size(); i++) {
            Date tempDate = listDate.get(i);
            if (tempMap.containsKey(tempDate)) {
                tempMap.put(tempDate, (Integer) tempMap.get(tempDate) + 1);
            } else {
                tempMap.put(tempDate, 1);
            }
        }
        return tempMap;
    }

    public List<Date> getFive(List<Date> listTm) {
        List<Date> listDate = new ArrayList<Date>();
        for (int i = 0; i < listTm.size(); i++) {

            if (listTm.get(i).getMinutes() != 0) {
                if (listTm.get(i).getMinutes() % 5 != 0) {
                    if (listTm.get(i).getMinutes() > 55) {
                        Date tempDate = null;
                        tempDate = new Date(listTm.get(i).getYear(), listTm.get(i).getMonth(), listTm.get(i).getDay(), listTm.get(i).getHours(), 0, 0);
                        Calendar ca = Calendar.getInstance();
                        ca.setTime(tempDate);
                        ca.add(Calendar.HOUR_OF_DAY, 1);
                        listDate.add(ca.getTime());
                    } else {
                        Date tempDate = null;
                        int minte = (listTm.get(i).getMinutes() / 5 + 1) * 5;
                        tempDate = new Date(listTm.get(i).getYear(), listTm.get(i).getMonth(), listTm.get(i).getDay(), listTm.get(i).getHours(), minte, 0);
                        listDate.add(tempDate);
                    }
                } else {
                    Date tempDate = null;
                    int minte = listTm.get(i).getMinutes();
                    tempDate = new Date(listTm.get(i).getYear(), listTm.get(i).getMonth(), listTm.get(i).getDay(), listTm.get(i).getHours(), minte, 0);
                    listDate.add(tempDate);
                }
            } else {
                Date tempDate = null;
                int minte = listTm.get(i).getMinutes();
                tempDate = new Date(listTm.get(i).getYear(), listTm.get(i).getMonth(), listTm.get(i).getDay(), listTm.get(i).getHours(), minte, 0);
                listDate.add(tempDate);
            }
        }
        return listDate;
    }

    /**
     * lhc 把固态水位数据报文写入文件
     *
     * @param msg
     */
    public void process06(String msg) throws IOException, ParseException {
        String path = RtuConfig.getMsgRcvPath();
        String stcd = String.valueOf(Integer.parseInt(msg.substring(4, 6), 16));
        String index = String.valueOf(Integer.parseInt(msg.substring(10, 14), 16));
        String endStr = msg.substring(msg.length() - 6, msg.length() - 4);
        // System.out.println(endStr);
        path = path + "/YY/rcv/" + stcd + "/06";
        File fullPathDir = new File(path);
        if (fullPathDir != null && !fullPathDir.exists()) {
            fullPathDir.mkdirs();
        }
        // 2、写入报文文件
        String fileName = index + ".msg";
        File file = new File(path, fileName);
        try {
            org.apache.commons.io.FileUtils.writeStringToFile(file, msg, "UTF8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //最后结尾是03代表数据发送结束，合并报文，统计五分钟数据入库.
        if (endStr.equals("03")) {
            process06End(stcd, path, Integer.parseInt(index));
        }
    }

    /**
     * 合并固态水位数据报文并入库五分钟数据
     */
    public void process06End(String stcd, String path, int sequence) throws IOException, ParseException {
        //取出文件夹下的所有问题，按照名称排序，第一个取出时间，后面的去掉前14个字符和后6个字符
        SimpleDateFormat sdf5 = new SimpleDateFormat("yyMMddHHmm");
        DateTime tm = null;//读取时间
        File fullPathDir = new File(path);
        File[] downFile = fullPathDir.listFiles();
        String content = "";
        if (downFile.length == sequence) {
            for (int i = 1; i <= sequence; i++) {
                String tempPath = path + "/" + i + ".msg";
                String msg = readToString(tempPath);
                if (i == 1) {
                    //取出时间
                    tm = new DateTime(sdf5.parse(msg.substring(20, 30)));
                    content += msg.substring(30, msg.length() - 6);
                } else {
                    content += msg.substring(14, msg.length() - 6);
                }
            }
            String[] zlist = new String[content.length() / 4];
            int index = 0;
            String z = "";
            //取出测站基本信息
            //写入业务数据库
            RtuStationModel station = StationManager.getInstance().getStation(stcd);
            logger.info("测站号码：" + stcd);
            if (station != null) {
                String stcd8 = station.getStcd8();
                for (int i = 0; i < content.length(); ) {
                    zlist[index] = content.substring(i, i + 4);
                    //不等于FFFF则入库数据
                    if (!org.apache.commons.lang3.StringUtils.endsWithIgnoreCase(zlist[index], "FFFF")) {
                        byte[] f5byte = ByteUtil.HexStringToBinary(zlist[index]);
                        int intvalue = ByteUtil.bytesToUshort(new byte[]{f5byte[0], f5byte[1]});
                        String itemvalue = Integer.toString(intvalue);
                        itemvalue = YYBuilder.buildDot(itemvalue, 2);
                        logger.debug("16进制:" + zlist[index] + " 水位值:" + itemvalue + "  时间:" + tm.toString("yyyy-MM-dd hh:mm:ss") + "   序号" + index + 1);
                        //写入五分钟水位
                        try {
                            writeYYConnvertData(stcd8, tm.toDate(), "1", 11, Double.parseDouble(itemvalue), 888);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    i = i + 4;
                    index++;
                    tm = tm.plusMinutes(5);
                }
            }
        }
        //清空文件夹
        delAllFile(path);
    }

    //删除指定文件夹下所有文件
//param path 文件夹完整绝对路径
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);//再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }
//删除文件夹
//param folderPath 文件夹完整绝对路径

    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); //删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
            myFilePath.delete(); //删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public String readToString(String fileName) {
        String encoding = "utf-8";
        File file = new File(fileName);
        Long filelength = file.length();
        byte[] filecontent = new byte[filelength.intValue()];
        try {
            FileInputStream in = new FileInputStream(file);
            in.read(filecontent);
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            return new String(filecontent, encoding);
        } catch (UnsupportedEncodingException e) {
            System.err.println("The OS does not support " + encoding);
            e.printStackTrace();
            return null;
        }
    }

    public String[] processSymbolF5H(byte[] value) {
        String[] dh12 = new String[12];
        int pos = 0;
        for (int i = 0, len = value.length; i < len; i = i + 2) {
            int intvalue = ByteUtil.bytesToUshort(new byte[]{value[i], value[i + 1]});

            if (intvalue == 65535) {
                dh12[pos] = "FFFF";
            } else {
                String itemvalue = Integer.toString(intvalue);
                itemvalue = YYBuilder.buildDot(itemvalue, 2);
                dh12[pos] = itemvalue;
            }

            pos++;
        }
        return dh12;
    }

    /**
     * 处理闸位数据，闸位数据为3*8=24字节，1个闸位数据为3字节，
     * 最高字节高4bit表示数据类型，1---表示闸位。最高字节低4bit表示闸位计号，其他2字节是闸位值，十六进制数
     * 示例数据：11 03 F6 12 04 5A 13 03 F6 14 03 F6 15 03 F6 16 03 F6 FF FF FF FF FF FF
     *
     * @param value
     * @return
     */
    public String[] processSymbolF8H(byte[] value) {
        String[] zw8 = new String[8];
        for (int i = 0; i < 8; i++) {
            zw8[i] = "FFFF";//对数组数据初始化
        }
        int pos = 0;
        int len = value.length / 3;
        for (int i = 0; i < len; i++) {
            pos = i * 3;
            byte flag = value[pos + 0];
            if (flag == (byte) 0xFF) {
                zw8[i] = "";
            } else {
                int intvalue = ByteUtil.bytesToShort(new byte[]{value[pos + 1], value[pos + 2]});
                //zw8[i] = String.valueOf(intvalue);
                zw8[i] = YYBuilder.buildDot(String.valueOf(intvalue), 2);
            }
        }
        return zw8;
    }

    /**
     * 处理流量数据，闸位数据为12*8=96字节，1个流量数据为8字节，
     *
     * @param value
     * @return
     */
    public String[] processSymbolF9H(byte[] value) {
        String[] zw12 = new String[12];
        for (int i = 0; i < 12; i++) {
            zw12[i] = "FFFFFFFFFFFFFFFF";//对数组数据初始化
        }
        int pos = 0;
        int len = value.length / 8;
        for (int i = 0; i < len; i++) {
            pos = i * 8;
            byte flag = value[pos + 0];
            String val = new String(new byte[]{value[pos + 0], value[pos + 1], value[pos + 2], value[pos + 3], value[pos + 4], value[pos + 5], value[pos + 6], value[pos + 7]});
            if (flag != (byte) 0xFF) {
                zw12[i] = val;
            }
        }
        return zw12;
    }

    public String processSymbolHex(byte[] value, int decimal) {

        if (value == null) return "";
        int intvalue = ByteUtil.bytesToUshort(value);
        return YYBuilder.buildDot(String.valueOf(intvalue), decimal);
    }

    public String processSymbolBcd(byte[] value, int decimal) {

        if (value == null) return "";
        String intvalue = ByteUtil.bcd2Str(value);
        return YYBuilder.buildDot(String.valueOf(intvalue), decimal);

    }

    public void setYyTel(String stcd, String tel, String flagHd, String center, String borrow) {

        //1、先查询，查询条件为测站编码stcd、时间ymdhm、数据类型valtyp、传感器编号devno、数据值deval //sjycdb.dbo.st_rtsr_r
        String searchSql = "select count(*) as cnt from rtu_station where stcd =?";
        int cnt = 0;
        cnt = dao.getJdbcTemplate().queryForRowSet(searchSql, new Object[]{stcd}).getRow();
        try {
            if (cnt == 0) {
                logger.debug(">>测站不存在，不能更新电话号码，测站号： " + stcd);
            } else {
                logger.debug(">>更新测站电话号码 测站号为： " + stcd + " 电话号码为 " + tel);
                String updateSql = "update rtu_station set  TELPHONE = ?,FLAG_HD=?,CENTER=?,BORROW=? where stcd =? ";
                dao.getJdbcTemplate().update(updateSql, new Object[]{tel, flagHd, center, borrow, stcd});
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 将消息写入数据库
     */
    private void writeDownMessage(BaseDao dao, String stcd, Date sendtime)
            throws Exception {

        try {

            java.util.Date now = new Date();

            long diff = now.getTime() - sendtime.getTime();

            // 判断时间如果大于2个小时，则产生下发时间召测报文
            if (Math.abs(diff) * 60 / HOUR > 5) {
                DownCommand cmd = new DownCommand();

                // Station station =
                // HydroServer.getInstance().getStationManager()
                // .getStation(stcd);
                //
                // if (StringUtils.isNotBlank(station.getF02())
                // && StringUtils.isNotBlank(station.getF03())) {
                // cmd.setStartBit(Symbol.SOH_HEX);
                // cmd.setCenterAddr(ByteUtil.HexStringToBinary(HydroConfig
                // .getCenterAddr()));
                // cmd.setStationAddr(ByteUtil.HexStringToBinary(station
                // .getF02()));
                // cmd.setPassword(ByteUtil.HexStringToBinary(station.getF03()));
                // cmd.setBodyStartBit(Symbol.STX);
                // cmd.setEof(Symbol.ENQ);
                // cmd.setFuncCode(new byte[] { 0x4A });
                // IMessage message = cmd.send37Message(0, null);
                //
                // String hexString = cmd.printHexString(message);
                //
                // byte[] hydroMessage = ByteUtil.HexStringToBinary(hexString);
                // boolean result = HydroServer.getInstance()
                // .getSessionManager()
                // .downMessage(stcd, hydroMessage);
                //
                // logger.info(">> 下发时间校对命令到【 " + stcd + " 】测站，下发结果【"
                // + (result ? "OK" : "WAIT") + "】，下发消息："
                // + cmd.printHexString(message));
                //
                // Map params = new HashMap();
                // // params.put("id", serial);
                // params.put("stcd", stcd);
                // params.put("func", "4A");
                // params.put("params", "");
                // params.put("message", hexString);
                // params.put("cmdtime", new Date(System.currentTimeMillis()));
                // params.put("sendtime", new Date(System.currentTimeMillis()));
                // params.put("flag", result ? 1 : 0);
                //
                // dao.insert("rtu_caller", new String[] { "stcd", "func",
                // "params", "message", "cmdtime","sendtime", "flag" }, params);
                // }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

// -----------------------------------------------

    private void writeDb(String mid, int serial, String stcd, String sttp,
                         Date sendDate, Date viewDate, String label, Object value)
            throws Exception {

        Map params = new HashMap();
        params.put("mid", mid);
        params.put("serial", serial);
        params.put("stcd", stcd);
        params.put("sttp", sttp);
        params.put("sendtime", sendDate);
        params.put("viewtime", viewDate);

        params.put("itemlabel", label.toUpperCase());
        params.put("itemvalue", value);

        params.put("writetime", new Date(System.currentTimeMillis()));

        try {
            dao.insert("rtu_message_r", new String[]{"mid", "serial", "stcd",
                    "sttp", "sendtime", "viewtime", "itemlabel", "itemvalue",
                    "writetime"}, params);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            // 添加写入文件的
        }
    }

    /**
     * 写入召测雨量数据
     *
     * @param mid
     * @param stcd
     * @param sttp
     * @param viewDate
     * @param label
     * @param value
     * @throws Exception
     */
    private void writeRtuCallerRain(String mid, String stcd, String sttp,
                                    Date viewDate, String label, Object value) throws Exception {

        Map params = new HashMap();

        params.put("mid", mid);
        params.put("id", UUID.randomUUID().toString());
        params.put("stcd", stcd);
        params.put("sttp", sttp);
        params.put("viewtime", viewDate);
        params.put("itemlabel", label.toUpperCase());
        params.put("itemvalue", value);
        params.put("writetime", new Date(System.currentTimeMillis()));
        params.put("flag", "0");

        try {
            dao.insert("rtu_caller_data", new String[]{"id", "mid", "stcd",
                    "sttp", "viewtime", "itemlabel", "itemvalue", "writetime",
                    "flag"}, params);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入召测水位数据
     *
     * @param mid
     * @param stcd
     * @param sttp
     * @param viewDate
     * @param voltage
     * @param channel
     * @param sendDate
     * @param label
     * @param value
     * @throws Exception
     */
    private void writeRtuCallerRiver(String mid, String stcd, String sttp,
                                     Date viewDate, double voltage, String channel, Date sendDate,
                                     String label, Object value) throws Exception {

        Map params = new HashMap();

        params.put("mid", mid);
        params.put("id", UUID.randomUUID().toString());
        params.put("stcd", stcd);
        params.put("sttp", sttp);
        params.put("viewtime", viewDate);
        params.put("itemlabel", label.toUpperCase());
        params.put("itemvalue", value);
        params.put("writetime", new Date(System.currentTimeMillis()));
        params.put("flag", "0");

        try {
            dao.insert("rtu_caller_data", new String[]{"id", "mid", "stcd",
                    "sttp", "viewtime", "itemlabel", "itemvalue", "writetime",
                    "flag"}, params);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void writeDb(String mid, int serial, String stcd, String sttp,
                         String sendDate, String viewDate, String label, String value)
            throws Exception {

        // 发送时间格式YYMMDDHHmmSS
        SimpleDateFormat sendtimeSdf = new SimpleDateFormat("yyMMddHHmmss");// yyyy-MM-dd
        // HH:mm:ss

        // 观测时间格式YYMMDDHHmm
        SimpleDateFormat viewtimeSdf = new SimpleDateFormat("yyMMddHHmm");// yyyy-MM-dd
        // HH:mm:ss

        Date sendDatetime = sendtimeSdf.parse(sendDate);

        Date viewDatetime = viewtimeSdf.parse(viewDate);

        this.writeDb(mid, serial, stcd, sttp, sendDatetime, viewDatetime,
                label, value);

    }

    public static void main(String[] arg) {

        byte[] aaa = new byte[2];

        String[] dh12 = new String[12];
        System.out.println(dh12.length);

        MessageYyConsumer xxx = new MessageYyConsumer();
        System.out.println(xxx.processSymbolHex(aaa, 1));

    }

}
